package com.xc.service.impl;

import com.ag.exception.SysTipsException;
import com.ag.utils.BigDecimals;
import com.ag.utils.NumberUtils;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.google.common.collect.Lists;
import com.xc.common.ServerResponse;
import com.xc.config.StockPoll;
import com.xc.dao.*;
import com.xc.pojo.*;
import com.xc.service.ISiteSettingService;
import com.xc.service.ISiteSpreadService;
import com.xc.service.IStockMarketsDayService;
import com.xc.service.IStockOptionService;
import com.xc.service.IStockService;
import com.xc.service.IUserService;
import com.xc.utils.HttpClientRequest;
import com.xc.utils.PropertiesUtil;
import com.xc.utils.stock.pinyin.GetPyByChinese;
import com.xc.utils.stock.qq.QqStockApi;
import com.xc.utils.stock.sina.SinaStockApi;
import com.xc.vo.stock.MarketVO;
import com.xc.vo.stock.MarketVOResult;
import com.xc.vo.stock.StockAdminListVO;
import com.xc.vo.stock.StockListVO;
import com.xc.vo.stock.StockVO;
import com.xc.vo.stock.k.MinDataVO;
import com.xc.vo.stock.k.echarts.EchartsDataVO;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.net.HttpURLConnection;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import org.apache.commons.lang3.RandomStringUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service("iStockService")
public class StockServiceImpl implements IStockService {
	private static final Logger log = LoggerFactory.getLogger(StockServiceImpl.class);

	@Autowired
	StockMapper stockMapper;

	@Autowired
	StockAllotmentMapper stockAllotmentMapper;
	
	@Autowired
	StockBlockTradeMapper stockBlockTradeMapper;

	@Autowired
	UserPositionMapper userPositionMapper;

	@Autowired
	UserMapper userMapper;


	@Autowired
	RealTimeMapper realTimeMapper;

	@Autowired
	IStockMarketsDayService iStockMarketsDayService;
	@Autowired
	ISiteSettingService iSiteSettingService;
	@Autowired
	ISiteSpreadService iSiteSpreadService;

	@Autowired
	StockPoll stockPoll;

	@Autowired
	StockFuturesMapper stockFuturesMapper;

	@Autowired
	StockIndexMapper stockIndexMapper;

	@Autowired
	IUserService iUserService;

	@Autowired
	IStockOptionService iStockOptionService;

	public ServerResponse getMarket() {
		String market_url = PropertiesUtil.getProperty("sina.market.url");
		String result = null;
		try {
			result = HttpClientRequest.doGet(market_url);
		} catch (Exception e) {
			log.error("e = {}", e);
		}
		String[] marketArray = result.split(";");
		List<MarketVO> marketVOS = Lists.newArrayList();
		for (int i = 0; i < marketArray.length; i++) {
			String hqstr = marketArray[i];
			try {
				if (StringUtils.isNotBlank(hqstr)) {
					hqstr = hqstr.substring(hqstr.indexOf("\"") + 1, hqstr.lastIndexOf("\""));
					MarketVO marketVO = new MarketVO();
					String[] sh01_arr = hqstr.split(",");
					marketVO.setName(sh01_arr[0]);
					marketVO.setNowPrice(sh01_arr[1]);
					marketVO.setIncrease(sh01_arr[2]);
					marketVO.setIncreaseRate(sh01_arr[3]);
					marketVOS.add(marketVO);
				}
			} catch (Exception e) {
				log.error("str = {} ,  e = {}", hqstr, e);
			}
		}
		MarketVOResult marketVOResult = new MarketVOResult();
		marketVOResult.setMarket(marketVOS);
		return ServerResponse.createBySuccess(marketVOResult);
	}

	public ServerResponse getStock(int pageNum, int pageSize, String keyWords, String stockPlate, String stockType,
			HttpServletRequest request) {
		PageHelper.startPage(pageNum, pageSize);
		User user = iUserService.getCurrentUser(request);
		List<Stock> stockList = this.stockMapper.findStockListByKeyWords(keyWords, stockPlate, stockType,
				Integer.valueOf(0));
		List<StockListVO> stockListVOS = Lists.newArrayList();
		if (stockList.size() > 0)
			for (Stock stock : stockList) {
				if(StringUtils.isBlank(stock.getStockType())) {
					continue;
				}
				StockListVO stockListVO = SinaStockApi
						.assembleStockListVO(SinaStockApi.getSinaStock(stock.getStockGid()));
				stockListVO.setCode(stock.getStockCode());
				stockListVO.setSpell(stock.getStockSpell());
				stockListVO.setGid(stock.getStockGid());
				BigDecimal day3Rate = (BigDecimal) selectRateByDaysAndStockCode(stock.getStockCode(), 3).getData();
				stockListVO.setDay3Rate(day3Rate);
				stockListVO.setStock_plate(stock.getStockPlate());
				stockListVO.setStock_type(stock.getStockType());
				// 是否添加自选
				if (user == null) {
					stockListVO.setIsOption("0");
				} else {
					stockListVO.setIsOption(iStockOptionService.isMyOption(user.getId(), stock.getStockCode()));
				}
				stockListVOS.add(stockListVO);
			}
		PageInfo pageInfo = new PageInfo(stockList);
		pageInfo.setList(stockListVOS);
		return ServerResponse.createBySuccess(pageInfo);
	}

	public void z1() {
		this.stockPoll.z1();
	}

	public void z11() {
		this.stockPoll.z11();
	}

	public void z12() {
		this.stockPoll.z12();
	}

	public void z2() {
		this.stockPoll.z2();
	}

	public void z21() {
		this.stockPoll.z21();
	}

	public void z22() {
		this.stockPoll.z22();
	}

	public void z3() {
		this.stockPoll.z3();
	}

	public void z31() {
		this.stockPoll.z31();
	}

	public void z32() {
		this.stockPoll.z32();
	}

	public void z4() {
		this.stockPoll.z4();
	}

	public void z41() {
		this.stockPoll.z41();
	}

	public void z42() {
		this.stockPoll.z42();
	}

	public void h1() {
		this.stockPoll.h1();
	}

	public void h11() {
		this.stockPoll.h11();
	}

	public void h12() {
		this.stockPoll.h12();
	}

	public void h2() {
		this.stockPoll.h2();
	}

	public void h21() {
		this.stockPoll.h21();
	}

	public void h22() {
		this.stockPoll.h22();
	}

	public void h3() {
		this.stockPoll.h3();
	}

	public void h31() {
		this.stockPoll.h31();
	}

	public void h32() {
		this.stockPoll.h32();
	}

	public ServerResponse getDateline(HttpServletResponse response, String code) {
		if (StringUtils.isBlank(code))
			return ServerResponse.createByErrorMsg("");
		Stock stock = this.stockMapper.findStockByCode(code);
		if (stock == null)
			return ServerResponse.createByErrorMsg("");
		response.setHeader("Access-Control-Allow-Origin", "*");
		Date time = new Date();
		SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
		String end = sdf.format(time);
		Calendar c = Calendar.getInstance();
		c.setTime(new Date());
		c.add(2, -3);
		Date m = c.getTime();
		String mon = sdf.format(m);
		String methodUrl = "http://q.stock.sohu.com/hisHq?code=cn_" + code + "+&start=" + mon + "&end=" + end
				+ "&stat=1&order=D";
		HttpURLConnection connection = null;
		BufferedReader reader = null;
		String line = null;
		EchartsDataVO echartsDataVO = new EchartsDataVO();
		try {
			URL url = new URL(methodUrl);
			connection = (HttpURLConnection) url.openConnection();
			connection.setRequestMethod("GET");
			connection.connect();
			if (connection.getResponseCode() == 200) {
				reader = new BufferedReader(new InputStreamReader(connection.getInputStream(), "gbk"));
				StringBuilder result = new StringBuilder();
				while ((line = reader.readLine()) != null)
					result.append(line).append(System.getProperty("line.separator"));
				JSONArray jsonArray = JSONArray.fromObject(result.toString());
				JSONObject json = jsonArray.getJSONObject(0);
				JSONArray jsonArray1 = JSONArray.fromObject(json.get("hq"));
				Collections.reverse((List<?>) jsonArray1);
				double[][] values = (double[][]) null;
				Object[][] volumes = (Object[][]) null;
				String[] date = null;
				values = new double[jsonArray1.size()][5];
				volumes = new Object[jsonArray1.size()][3];
				date = new String[jsonArray1.size()];
				for (int i = 0; i < jsonArray1.size(); i++) {
					JSONArray js = JSONArray.fromObject(jsonArray1.get(i));
					date[i] = js.get(0).toString();
					values[i][0] = Double.valueOf(js.get(1).toString()).doubleValue();
					values[i][1] = Double.valueOf(js.get(2).toString()).doubleValue();
					values[i][2] = Double.valueOf(js.get(5).toString()).doubleValue();
					values[i][3] = Double.valueOf(js.get(6).toString()).doubleValue();
					values[i][4] = Double.valueOf(js.get(7).toString()).doubleValue();
					volumes[i][0] = Integer.valueOf(i);
					volumes[i][1] = Double.valueOf(js.get(7).toString());
					volumes[i][2] = Integer
							.valueOf((Double.valueOf(js.get(3).toString()).doubleValue() > 0.0D) ? 1 : -1);
				}
				echartsDataVO.setDate(date);
				echartsDataVO.setValues(values);
				echartsDataVO.setVolumes(volumes);
				echartsDataVO.setStockCode(stock.getStockCode());
				echartsDataVO.setStockName(stock.getStockName());
				log.info(String.valueOf(echartsDataVO));
				ServerResponse.createBySuccess(echartsDataVO);
			}
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				reader.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
			connection.disconnect();
		}
		return ServerResponse.createBySuccess(echartsDataVO);
	}

	public ServerResponse getSingleStock(String code) {
		if (StringUtils.isBlank(code))
			return ServerResponse.createByErrorMsg("");
		Stock stock = new Stock();
		Integer depositAmt = 0;
		// 期货
		if (code.contains("hf")) {
			StockFutures futmodel = stockFuturesMapper.selectFuturesByCode(code.replace("hf_", ""));
			stock.setStockGid(futmodel.getFuturesGid());
			stock.setStockCode(futmodel.getFuturesCode());
			stock.setStockName(futmodel.getFuturesName());
			stock.setAddTime(futmodel.getAddTime());
			stock.setId(futmodel.getId());
			stock.setStockSpell("0");
			depositAmt = futmodel.getDepositAmt();
		} else if (code.contains("sh") || code.contains("sz")) { // 指数
			StockIndex model = stockIndexMapper.selectIndexByCode(code.replace("sh", "").replace("sz", ""));
			stock.setStockGid(model.getIndexGid());
			stock.setStockCode(model.getIndexCode());
			stock.setStockName(model.getIndexName());
			stock.setAddTime(model.getAddTime());
			stock.setId(model.getId());
			stock.setStockSpell("0");
			depositAmt = model.getDepositAmt();
		} else {// 股票
			stock = this.stockMapper.findStockByCode(code);
		}

		if (stock == null)
			return ServerResponse.createByErrorMsg("");
		String gid = stock.getStockGid();
		String sinaResult = SinaStockApi.getSinaStock(gid);
		StockVO stockVO = new StockVO();
		if (code.contains("hf")) {
			stockVO = SinaStockApi.assembleStockFuturesVO(sinaResult);
		} else {
			stockVO = SinaStockApi.assembleStockVO(sinaResult);
		}
		stockVO.setDepositAmt(depositAmt);
		stockVO.setId(stock.getId().intValue());
		stockVO.setCode(stock.getStockCode());
		stockVO.setSpell(stock.getStockSpell());
		stockVO.setGid(stock.getStockGid());
		stockVO.setMinImg(PropertiesUtil.getProperty("sina.single.stock.min.url") + stock.getStockGid() + ".jpg");
		stockVO.setDayImg(PropertiesUtil.getProperty("sina.single.stock.day.url") + stock.getStockGid() + ".jpg");
		stockVO.setWeekImg(PropertiesUtil.getProperty("sina.single.stock.week.url") + stock.getStockGid() + ".jpg");
		stockVO.setMonthImg(PropertiesUtil.getProperty("sina.single.stock.month.url") + stock.getStockGid() + ".jpg");
		return ServerResponse.createBySuccess(stockVO);
	}

	public ServerResponse getMinK(String code, Integer time, Integer ma, Integer size) {
		if (StringUtils.isBlank(code) || time == null || ma == null || size == null)
			return ServerResponse.createByErrorMsg("");
		Stock stock = this.stockMapper.findStockByCode(code);
		if (stock == null)
			return ServerResponse.createByErrorMsg("");
		return SinaStockApi.getStockMinK(stock, time.intValue(), ma.intValue(), size.intValue());
	}

	public ServerResponse getMinK_Echarts(String code, Integer time, Integer ma, Integer size) {
		if (StringUtils.isBlank(code) || time == null || ma == null || size == null)
			return ServerResponse.createByErrorMsg("");
		Stock stock = this.stockMapper.findStockByCode(code);
		if (stock == null)
			return ServerResponse.createByErrorMsg("");
		ServerResponse<MinDataVO> serverResponse = SinaStockApi.getStockMinK(stock, time.intValue(), ma.intValue(),
				size.intValue());
		MinDataVO minDataVO = (MinDataVO) serverResponse.getData();
		EchartsDataVO echartsDataVO = SinaStockApi.assembleEchartsDataVO(minDataVO);
		return ServerResponse.createBySuccess(echartsDataVO);
	}

	/* 期货分时-k线 */
	public ServerResponse getFuturesMinK_Echarts(String code, Integer time, Integer size) {
		if (StringUtils.isBlank(code) || time == null)
			return ServerResponse.createByErrorMsg("");
		StockFutures stock = this.stockFuturesMapper.selectFuturesByCode(code.split("_")[1]);
		if (stock == null)
			return ServerResponse.createByErrorMsg("");
		ServerResponse<MinDataVO> serverResponse = SinaStockApi.getFuturesMinK(stock, time.intValue(), size.intValue());
		MinDataVO minDataVO = (MinDataVO) serverResponse.getData();
		EchartsDataVO echartsDataVO = SinaStockApi.assembleEchartsDataVO(minDataVO);
		return ServerResponse.createBySuccess(echartsDataVO);
	}

	/* 指数分时-k线 */
	public ServerResponse getIndexMinK_Echarts(String code, Integer time, Integer size) {
		if (StringUtils.isBlank(code) || time == null)
			return ServerResponse.createByErrorMsg("");
		StockIndex stock = this.stockIndexMapper.selectIndexByCode(code.replace("sh", "").replace("sz", ""));
		if (stock == null)
			return ServerResponse.createByErrorMsg("");
		ServerResponse<MinDataVO> serverResponse = SinaStockApi.getIndexMinK(stock, time.intValue(), size.intValue());
		MinDataVO minDataVO = (MinDataVO) serverResponse.getData();
		EchartsDataVO echartsDataVO = SinaStockApi.assembleEchartsDataVO(minDataVO);
		return ServerResponse.createBySuccess(echartsDataVO);
	}

	/* 股票日线-K线 */
	public ServerResponse getDayK_Echarts(String code) {
		return kEcharts(code, "day");
	}

	ServerResponse kEcharts(String code, String type) {
		if (StringUtils.isBlank(code))
			return ServerResponse.createByErrorMsg("");
		Stock stock = this.stockMapper.findStockByCode(code);
		if (stock == null)
			return ServerResponse.createByErrorMsg("");
		ServerResponse<MinDataVO> serverResponse = QqStockApi.getGpStockMonthK(stock, type);
		MinDataVO minDataVO = (MinDataVO) serverResponse.getData();
		EchartsDataVO echartsDataVO = SinaStockApi.assembleEchartsDataVO(minDataVO);
		return ServerResponse.createBySuccess(echartsDataVO);
	}

	/* 股票周线-K线 */
	public ServerResponse getWeekK_Echarts(String code) {
		return kEcharts(code, "week");
	}

	/* 股票月线-K线 */
	public ServerResponse getMonthK_Echarts(String code) {
		return kEcharts(code, "month");
	}

	/* 期货日线-K线 */
	public ServerResponse getFuturesDayK(String code) {
		if (StringUtils.isBlank(code))
			return ServerResponse.createByErrorMsg("");
		StockFutures stock = this.stockFuturesMapper.selectFuturesByCode(code.split("_")[1]);
		if (stock == null)
			return ServerResponse.createByErrorMsg("");
		ServerResponse<MinDataVO> serverResponse = QqStockApi.getQqStockDayK(stock);
		MinDataVO minDataVO = (MinDataVO) serverResponse.getData();
		EchartsDataVO echartsDataVO = SinaStockApi.assembleEchartsDataVO(minDataVO);
		return ServerResponse.createBySuccess(echartsDataVO);
	}

	/* 指数日线-K线 */
	public ServerResponse getIndexDayK(String code) {
		if (StringUtils.isBlank(code))
			return ServerResponse.createByErrorMsg("");
		StockIndex stock = this.stockIndexMapper.selectIndexByCode(code.replace("sh", "").replace("sz", ""));
		if (stock == null)
			return ServerResponse.createByErrorMsg("");
		ServerResponse<MinDataVO> serverResponse = QqStockApi.getQqIndexDayK(stock);
		MinDataVO minDataVO = (MinDataVO) serverResponse.getData();
		EchartsDataVO echartsDataVO = SinaStockApi.assembleEchartsDataVO(minDataVO);
		return ServerResponse.createBySuccess(echartsDataVO);
	}

	public ServerResponse<Stock> findStockByName(String name) {
		return ServerResponse.createBySuccess(this.stockMapper.findStockByName(name));
	}

	public ServerResponse<Stock> findStockByCode(String code) {
		return ServerResponse.createBySuccess(this.stockMapper.findStockByCode(code));
	}

	public ServerResponse<Stock> findStockById(Integer stockId) {
		return ServerResponse.createBySuccess(this.stockMapper.selectByPrimaryKey(stockId));
	}

	public ServerResponse<PageInfo> listByAdmin(Integer showState, Integer lockState, String code, String name,
			String stockPlate, String stockType, int pageNum, int pageSize, HttpServletRequest request) {
		PageHelper.startPage(pageNum, pageSize);
		List<Stock> stockList = this.stockMapper.listByAdmin(showState, lockState, code, name, stockPlate, stockType);
		List<StockAdminListVO> stockAdminListVOS = Lists.newArrayList();
		for (Stock stock : stockList) {
			StockAdminListVO stockAdminListVO = assembleStockAdminListVO(stock);
			stockAdminListVOS.add(stockAdminListVO);
		}
		PageInfo pageInfo = new PageInfo(stockList);
		pageInfo.setList(stockAdminListVOS);
		return ServerResponse.createBySuccess(pageInfo);
	}

	public ServerResponse<PageInfo> listAllotment(String stockName, String stockCode, Integer pageNum, Integer pageSize) {
		PageHelper.startPage(pageNum, pageSize);
		List<StockAllotment> stockList = this.stockAllotmentMapper.listByAdmin(stockName, stockCode);
		PageInfo pageInfo = new PageInfo(stockList);
		pageInfo.setList(stockList);
		return ServerResponse.createBySuccess(pageInfo);
	}
	
	public ServerResponse<PageInfo> listBlockTrade(Integer showState, Integer lockState, String code,  int pageNum, int pageSize, HttpServletRequest request) {
		PageHelper.startPage(pageNum, pageSize);
		List<StockBlockTrade> stockList = this.stockBlockTradeMapper.listByAdmin(showState, lockState, code);
		PageInfo pageInfo = new PageInfo(stockList);
		pageInfo.setList(stockList);
		return ServerResponse.createBySuccess(pageInfo);
	}

	public ServerResponse<PageInfo> listNewStockApply(  int pageNum, int pageSize, Map<String, Object> map, HttpServletRequest request) {
		PageHelper.startPage(pageNum, pageSize);
		List<UserPosition> stockList = this.userPositionMapper.listNewStockApply(map);
		PageInfo pageInfo = new PageInfo(stockList);
		pageInfo.setList(stockList);
		return ServerResponse.createBySuccess(pageInfo);
	}
	public ServerResponse<PageInfo> listStockAllotmentApply(  int pageNum, int pageSize, Map<String, Object> map, HttpServletRequest request) {
		PageHelper.startPage(pageNum, pageSize);
		List<UserPosition> stockList = this.userPositionMapper.listStockAllotmentApply(map);
		PageInfo pageInfo = new PageInfo(stockList);
		pageInfo.setList(stockList);
		return ServerResponse.createBySuccess(pageInfo);
	}
	public ServerResponse<PageInfo> listStockBlockTradeApply(int pageNum, int pageSize, Map<String, Object> map, HttpServletRequest request) {
		PageHelper.startPage(pageNum, pageSize);
		List<UserPosition> stockList = this.userPositionMapper.listStockBlockTradeApply(map);
		PageInfo pageInfo = new PageInfo(stockList);
		pageInfo.setList(stockList);
		return ServerResponse.createBySuccess(pageInfo);
	}

	@Transactional
	public ServerResponse opNewStockApply(  int id, int state, Integer passNum) throws Exception {
		UserPosition userPosition =	this.userPositionMapper.findPositionById(id);
		if(state == 1) {
			checkPassIfNeedRefund(userPosition, passNum);
		} else if (state == 2) { //1审核中签 2 未中签
			if (userPosition != null) {
				//返还资金到客户余额
			    User user =	this.userMapper.findById(userPosition.getUserId());
				user.setEnableAmt(user.getEnableAmt().add(userPosition.getOrderTotalPrice()));
				int updateUserCount = this.userMapper.updateByPrimaryKeySelective(user);
				if (updateUserCount > 0) {
					log.info("【配售】修改用户金额成功");
				} else {
					log.error("【配售】修改用户金额出错");
					throw new Exception("【配售】修改用户金额出错");
				}
			}
		}
		Integer res = this.userPositionMapper.opNewStockApply(id,state);
		if (res>0) {
			return ServerResponse.createBySuccessMsg("操作成功");
		}
		return ServerResponse.createByErrorMsg("操作失败");
	}
	
	/**
	 *  部分通过时的退用户金额
	 * @param userPosition
	 * @param passNum
	 */
	@Transactional
	public void checkPassIfNeedRefund(UserPosition userPosition, Integer passNum) {
		String mark = "未知";
		if(userPosition.getPositionType() == 4) {
			mark = "【配售】";
		} else if(userPosition.getPositionType() == 2) {
			mark = "【申购】";
		} else if(userPosition.getPositionType() == 3) {
			mark = "【大宗交易】";
		}
		
		if(NumberUtils.isNotValid(passNum)) {
			throw new RuntimeException(mark + "中签时股数非法");
		}
		
		if(passNum > userPosition.getOrderNum()) {
			throw new RuntimeException(mark + "中签时passNum非法, 不能大于总数");
		}
		
		if(passNum == userPosition.getOrderNum()) {//全部数量通过, 无需退用户金额
			return;
		}
		
		SiteSetting siteSetting = this.iSiteSettingService.getSiteSetting();
        if (siteSetting == null) {
            log.error("下单出错，网站设置表不存在");
            throw new RuntimeException(mark + "系统设置错误");
        }
        
        BigDecimal origOrderTotlePrice = userPosition.getOrderTotalPrice();
        
        BigDecimal renewCalcOrderTotlePrice = BigDecimals.multiplys(passNum, userPosition.getBuyOrderPrice());
        
        userPosition.setOrderTotalPrice(renewCalcOrderTotlePrice);
        
		//递延费特殊处理
        BigDecimal stayFee = renewCalcOrderTotlePrice.multiply(siteSetting.getStayFee());
        BigDecimal allStayFee = stayFee.multiply(new BigDecimal(1));
        userPosition.setOrderStayFee(allStayFee);
        userPosition.setOrderStayDays(1);

        BigDecimal buy_fee_amt = renewCalcOrderTotlePrice.multiply(siteSetting.getBuyFee()).setScale(2, 4);
        log.info("用户购买手续费（配资后总资金 * 百分比） = {}", buy_fee_amt);
        userPosition.setOrderFee(buy_fee_amt);


        BigDecimal buy_yhs_amt = renewCalcOrderTotlePrice.multiply(siteSetting.getDutyFee()).setScale(2, 4);
        log.info("用户购买印花税（配资后总资金 * 百分比） = {}", buy_yhs_amt);
        userPosition.setOrderSpread(buy_yhs_amt);

//        SiteSpread siteSpread = iSiteSpreadService.findSpreadRateOne(new BigDecimal(stock_crease), renewCalcOrderTotlePrice, stock.getStockCode(), now_price);
        BigDecimal spread_rate_amt = new BigDecimal("0");
//        if(siteSpread != null){
//            spread_rate_amt = renewCalcOrderTotlePrice.multiply(siteSpread.getSpreadRate()).setScale(2, 4);
//            log.info("用户购买点差费（配资后总资金 * 百分比{}） = {}", siteSpread.getSpreadRate(), spread_rate_amt);
//        } else{
//            log.info("用户购买点差费（配资后总资金 * 百分比{}） = {}", "设置异常", spread_rate_amt);
//        }
//
//        userPosition.setSpreadRatePrice(spread_rate_amt);
        userPosition.setSpreadRatePrice(BigDecimal.ZERO);

        BigDecimal profit_and_lose = new BigDecimal("0");
        userPosition.setProfitAndLose(profit_and_lose);


        BigDecimal all_profit_and_lose = profit_and_lose.subtract(buy_fee_amt).subtract(buy_yhs_amt).subtract(spread_rate_amt);
        userPosition.setAllProfitAndLose(all_profit_and_lose);

        userPosition.setOrderStayDays(Integer.valueOf(0));
        userPosition.setOrderStayFee(new BigDecimal("0"));
        
		
//		BigDecimal refundPercent = BigDecimals.divide(userPosition.getOrderNum() - passNum, userPosition.getOrderNum()).setScale(4, RoundingMode.HALF_DOWN);
//		
//		//allProfitAndLose = profitAndLose.subtract(position.getOrderFee()).subtract(position.getOrderSpread()).subtract(position.getOrderStayFee()).subtract(position.getSpreadRatePrice());
//		BigDecimal refundStockAmount = BigDecimals.multiplys(passNum, userPosition.getBuyOrderPrice());
//		BigDecimal refundOrderFee = BigDecimals.multiplys(userPosition.getOrderFee(), refundPercent).setScale(2, RoundingMode.HALF_DOWN);
//		BigDecimal refundOrderSpread = BigDecimals.multiplys(userPosition.getOrderSpread(), refundPercent).setScale(2, RoundingMode.HALF_DOWN);
//		BigDecimal refundOrderStayFee = BigDecimals.multiplys(userPosition.getOrderStayFee(), refundPercent).setScale(2, RoundingMode.HALF_DOWN);
//		BigDecimal refundSpreadRatePrice = BigDecimals.multiplys(userPosition.getSpreadRatePrice(), refundPercent).setScale(2, RoundingMode.HALF_DOWN);
//		
//		log.info(mark + "部分通过, id:{},passNum:{},  refundStockAmount:{}, refundOrderFee: {}, refundOrderSpread:{}, refundOrderStayFee:{}, refundSpreadRatePrice:{}", new Object[] {
//				userPosition.getId(), passNum,refundStockAmount,refundOrderFee,refundOrderSpread,refundOrderStayFee,refundSpreadRatePrice
//		});
//		BigDecimal refundTotal = BigDecimals.add(refundStockAmount, refundOrderFee, refundOrderSpread, refundOrderStayFee, refundSpreadRatePrice);
        
		BigDecimal refundTotal = BigDecimals.subtract(origOrderTotlePrice, renewCalcOrderTotlePrice);
		User user =	this.userMapper.findById(userPosition.getUserId());
		user.setEnableAmt(user.getEnableAmt().add(refundTotal));
		int updateUserCount = this.userMapper.updateByPrimaryKeySelective(user);
		if (updateUserCount > 0) {
			log.info(mark + "修改用户金额成功, refundTotal: {}, origOrderTotlePrice: {}, renewCalcOrderTotlePrice: {}", refundTotal, origOrderTotlePrice, renewCalcOrderTotlePrice);
		} else {
			log.error(mark + "修改用户金额出错");
			throw new RuntimeException(mark + "修改用户金额出错");
		}
		
		userPosition.setOrderNum(passNum);
//		userPosition.setOrderTotalPrice(BigDecimals.subtract(userPosition.getOrderTotalPrice(), refundStockAmount));
//		userPosition.setOrderFee(BigDecimals.subtract(userPosition.getOrderFee(), refundOrderFee));
//		userPosition.setOrderSpread(BigDecimals.subtract(userPosition.getOrderSpread(), refundOrderSpread));
//		userPosition.setOrderStayFee(BigDecimals.subtract(userPosition.getOrderStayFee(), refundOrderStayFee));
//		userPosition.setSpreadRatePrice(BigDecimals.subtract(userPosition.getSpreadRatePrice(), refundSpreadRatePrice));
		
		int count = this.userPositionMapper.updateByPrimaryKeySelective(userPosition);
		userPositionMapper.insertPositionHistory(userPosition.getId());
		if (count > 0) {
			log.info("【配售】修改持仓成功");
		} else {
			log.error("【配售】修改持仓出错");
			throw new RuntimeException("【配售】修改持仓出错");
		}
	}

	@Transactional
	public ServerResponse opStockBlockTradeApply(  int id, int state, Integer passNum) throws Exception {
		UserPosition userPosition =	this.userPositionMapper.findPositionById(id);
		if(state == 1) {
			checkPassIfNeedRefund(userPosition, passNum);
		} else if (state == 2) { //1审核中签 2 未中签
			if (userPosition != null) {
				//返还资金到客户余额
				User user =	this.userMapper.findById(userPosition.getUserId());
				user.setEnableAmt(user.getEnableAmt().add(userPosition.getOrderTotalPrice()));
				int updateUserCount = this.userMapper.updateByPrimaryKeySelective(user);
				if (updateUserCount > 0) {
					log.info("【新股申购】修改用户金额成功");
				} else {
					log.error("新股申购】修改用户金额出错");
					throw new Exception("新股申购】修改用户金额出错");
				}
			}
		}
		Integer res = this.userPositionMapper.opStockBlockTradeApply(id,state);
		if (res>0) {
			return ServerResponse.createBySuccessMsg("操作成功");
		}
		return ServerResponse.createByErrorMsg("操作失败");
	}
	@Transactional
	public ServerResponse opStockAllotmentApply(  int id, int state, Integer passNum) throws Exception {
		UserPosition userPosition =	this.userPositionMapper.findPositionById(id);
		if(state == 1) {
			checkPassIfNeedRefund(userPosition, passNum);
		} else if (state == 2) { //1审核中签 2 未中签
			if (userPosition != null) {
				//返还资金到客户余额
				User user =	this.userMapper.findById(userPosition.getUserId());
				user.setEnableAmt(user.getEnableAmt().add(userPosition.getOrderTotalPrice()));
				int updateUserCount = this.userMapper.updateByPrimaryKeySelective(user);
				if (updateUserCount > 0) {
					log.info("【大宗交易】修改用户金额成功");
				} else {
					log.error("【大宗交易】修改用户金额出错");
					// 【大宗交易】修改用户金额出错
					throw new SysTipsException("tips.msg.099");
				}
			}
		}
		Integer res = this.userPositionMapper.opStockBlockTradeApply(id,state);
		if (res>0) {
			// 操作成功
			return ServerResponse.createBySuccessMsg("tips.msg.101");
		}
		// 操作失败
		return ServerResponse.createByErrorMsg("tips.msg.102");
	}

	private StockAdminListVO assembleStockAdminListVO(Stock stock) {
		StockAdminListVO stockAdminListVO = new StockAdminListVO();
		stockAdminListVO.setId(stock.getId());
		stockAdminListVO.setStockName(stock.getStockName());
		stockAdminListVO.setStockCode(stock.getStockCode());
		stockAdminListVO.setStockSpell(stock.getStockSpell());
		stockAdminListVO.setStockType(stock.getStockType());
		stockAdminListVO.setStockGid(stock.getStockGid());
		stockAdminListVO.setStockPlate(stock.getStockPlate());
		stockAdminListVO.setIsLock(stock.getIsLock());
		stockAdminListVO.setIsShow(stock.getIsShow());
		stockAdminListVO.setAddTime(stock.getAddTime());
		StockListVO stockListVO = SinaStockApi.assembleStockListVO(SinaStockApi.getSinaStock(stock.getStockGid()));
		stockAdminListVO.setNowPrice(stockListVO.getNowPrice());
		stockAdminListVO.setHcrate(stockListVO.getHcrate());
		stockAdminListVO.setSpreadRate(stock.getSpreadRate());
		ServerResponse serverResponse = selectRateByDaysAndStockCode(stock.getStockCode(), 3);
		BigDecimal day3Rate = new BigDecimal("0");
		if (serverResponse.isSuccess())
			day3Rate = (BigDecimal) serverResponse.getData();
		stockAdminListVO.setDay3Rate(day3Rate);
		return stockAdminListVO;
	}


	public ServerResponse updateLock(Integer stockId) {
		Stock stock = this.stockMapper.selectByPrimaryKey(stockId);
		if (stock == null)
			return ServerResponse.createByErrorMsg("");
		if (stock.getIsLock().intValue() == 1) {
			stock.setIsLock(Integer.valueOf(0));
		} else {
			stock.setIsLock(Integer.valueOf(1));
		}
		int updateCount = this.stockMapper.updateByPrimaryKeySelective(stock);
		if (updateCount > 0)
			return ServerResponse.createBySuccessMsg("");
		return ServerResponse.createByErrorMsg("");
	}

	public ServerResponse updateShow(Integer stockId) {
		Stock stock = this.stockMapper.selectByPrimaryKey(stockId);
		if (stock == null)
			return ServerResponse.createByErrorMsg("");
		if (stock.getIsShow().intValue() == 0) {
			stock.setIsShow(Integer.valueOf(1));
		} else {
			stock.setIsShow(Integer.valueOf(0));
		}
		int updateCount = this.stockMapper.updateByPrimaryKeySelective(stock);
		if (updateCount > 0)
			return ServerResponse.createBySuccessMsg("");
		return ServerResponse.createByErrorMsg("");
	}

	public ServerResponse addStock(String stockName, String stockCode, String stockType, String stockPlate,
			Integer isLock, Integer isShow) {
		if (StringUtils.isBlank(stockName) || StringUtils.isBlank(stockCode) || StringUtils.isBlank(stockType)
				|| isLock == null || isShow == null)
			return ServerResponse.createByErrorMsg("参数不能为空");
		Stock cstock = (Stock) findStockByCode(stockCode).getData();
		if (cstock != null)
			return ServerResponse.createByErrorMsg("当前股票代码已存在");
		Stock nstock = (Stock) findStockByName(stockName).getData();
		if (nstock != null)
			return ServerResponse.createByErrorMsg("当前股票名称已存在");
		Stock stock = new Stock();
		stock.setStockName(stockName);
		stock.setStockCode(stockCode);
		stock.setStockSpell(GetPyByChinese.converterToFirstSpell(stockName));
		stock.setStockType(stockType);
		stock.setStockGid(stockType + stockCode);
		stock.setIsLock(isLock);
		stock.setIsShow(isShow);
		stock.setAddTime(new Date());
		if (stockPlate != null)
			stock.setStockPlate(stockPlate);

		if (stockPlate != null && StringUtils.isNotEmpty(stockPlate) && stockCode.startsWith("300"))
			stock.setStockPlate("创业");
		else if (stockPlate != null && StringUtils.isNotEmpty(stockPlate) && stockCode.startsWith("688"))
			stock.setStockPlate("科创");
		else
			stock.setStockPlate(null);

		int insertCount = this.stockMapper.insert(stock);
		if (insertCount > 0)
			return ServerResponse.createBySuccessMsg("操作成功");
		return ServerResponse.createByErrorMsg("操作失败");
	}

	public ServerResponse addAllotment(StockAllotment model) {
		if (StringUtils.isBlank(model.getStockName()) || StringUtils.isBlank(model.getStockCode()))
			return ServerResponse.createByErrorMsg("");
		Stock ostock = this.stockMapper.findStockByCode(model.getStockCode());
		if (ostock == null) {
			return ServerResponse.createByErrorMsg("大宗交易股票信息有误，请核对后再添加");
		}
		StockAllotment cstock = this.stockAllotmentMapper.findStockByCode(model.getStockCode());
		if (cstock != null)
			return ServerResponse.createByErrorMsg("此配售股票已经添加，无需重复添加");

		StockAllotment stock = new StockAllotment();
		stock.setStockName(model.getStockName());
		stock.setStockCode(model.getStockCode());
		stock.setTotal(model.getTotal());
		stock.setStockCode(model.getStockCode());
		stock.setIsLock(0);
		stock.setIsShow(0);
		stock.setPrice(model.getPrice());
		stock.setVerifyCode( RandomStringUtils.randomNumeric(6));
		Integer res = this.stockAllotmentMapper.insert(stock);
		if (res>0)
			return ServerResponse.createBySuccessMsg("添加成功");
		return ServerResponse.createByErrorMsg("添加失败");
	}
	
	public ServerResponse addBlockTrade(StockBlockTrade model) {
		if (StringUtils.isBlank(model.getStockName()) || StringUtils.isBlank(model.getStockCode()))
			return ServerResponse.createByErrorMsg("");
		Stock ostock = this.stockMapper.findStockByCode(model.getStockCode());
		if (ostock == null) {
			return ServerResponse.createByErrorMsg("配售股票信息有误，请核对后再添加");
		}
		StockBlockTrade cstock = this.stockBlockTradeMapper.findStockByCode(model.getStockCode());
		if (cstock != null)
			return ServerResponse.createByErrorMsg("此配售股票已经添加，无需重复添加");
		
		StockBlockTrade stock = new StockBlockTrade();
		stock.setStockName(model.getStockName());
		stock.setStockCode(model.getStockCode());
		stock.setTotal(model.getTotal());
		stock.setStockCode(model.getStockCode());
		stock.setPrice(model.getPrice());
		stock.setIsLock(0);
		stock.setIsShow(0);
		stock.setVerifyCode( RandomStringUtils.randomNumeric(6));
		Integer res = this.stockBlockTradeMapper.insert(stock);
		if (res > 0)
			return ServerResponse.createBySuccessMsg("添加成功");
		return ServerResponse.createByErrorMsg("添加失败");
	}

	public int CountStockNum() {
		return this.stockMapper.CountStockNum();
	}

	public int CountShowNum(Integer showState) {
		return this.stockMapper.CountShowNum(showState);
	}

	public int CountUnLockNum(Integer lockState) {
		return this.stockMapper.CountUnLockNum(lockState);
	}

	public List findStockList() {
		return this.stockMapper.findStockList();
	}

	public ServerResponse selectRateByDaysAndStockCode(String stockCode, int days) {
		Stock stock = this.stockMapper.findStockByCode(stockCode);
		if (stock == null)
			return ServerResponse.createByErrorMsg("");
		BigDecimal daysRate = this.iStockMarketsDayService.selectRateByDaysAndStockCode(stock.getId(), days);
		return ServerResponse.createBySuccess(daysRate);
	}

	public ServerResponse updateStock(Stock model) {
		if (StringUtils.isBlank(model.getId().toString()) || StringUtils.isBlank(model.getStockName()))
			return ServerResponse.createByErrorMsg("");
		Stock stock = this.stockMapper.selectByPrimaryKey(model.getId());
		if (stock == null)
			return ServerResponse.createByErrorMsg("");
		stock.setStockName(model.getStockName());
		if (model.getSpreadRate() != null)
			stock.setSpreadRate(model.getSpreadRate());
		int updateCount = this.stockMapper.updateByPrimaryKeySelective(stock);
		if (updateCount > 0)
			return ServerResponse.createBySuccessMsg("");
		return ServerResponse.createByErrorMsg("");
	}
	public ServerResponse updateStockAllotment(StockAllotment model) {
		if (StringUtils.isBlank(model.getId().toString()) )
			return ServerResponse.createByErrorMsg("股票id不能为空");
		StockAllotment stock = this.stockAllotmentMapper.selectByPrimaryKey(model.getId());
		if (stock == null)
			return ServerResponse.createByErrorMsg("未查询到该股票信息");
		StockAllotment newStock = new StockAllotment();
		newStock.setStockCode(model.getStockCode());
		newStock.setStockName(model.getStockName());
		newStock.setTotal(model.getTotal());
		newStock.setIsShow(model.getIsShow());
		newStock.setIsLock(model.getIsLock());
		newStock.setApply(model.getApply());
		newStock.setPrice(model.getPrice());
		newStock.setId(stock.getId());
		int updateCount = this.stockAllotmentMapper.updateByPrimaryKeySelective(newStock);
		if (updateCount > 0)
			return ServerResponse.createBySuccessMsg("修改成功");

		return ServerResponse.createByErrorMsg("修改失败");
	}
	
	public ServerResponse updateStockBlockTrade(StockBlockTrade model) {
		if (StringUtils.isBlank(model.getId().toString()) )
			return ServerResponse.createByErrorMsg("股票id不能为空");
		StockBlockTrade stock = this.stockBlockTradeMapper.selectByPrimaryKey(model.getId());
		if (stock == null)
			return ServerResponse.createByErrorMsg("未查询到该股票信息");
		StockBlockTrade newStock = new StockBlockTrade();
		newStock.setStockCode(model.getStockCode());
		newStock.setStockName(model.getStockName());
		newStock.setTotal(model.getTotal());
		newStock.setIsShow(model.getIsShow());
		newStock.setIsLock(model.getIsLock());
		newStock.setApply(model.getApply());
		newStock.setPrice(model.getPrice());
		newStock.setId(stock.getId());
		int updateCount = this.stockBlockTradeMapper.updateByPrimaryKeySelective(newStock);
		if (updateCount > 0)
			return ServerResponse.createBySuccessMsg("修改成功");

		return ServerResponse.createByErrorMsg("修改失败");
	}
	public ServerResponse deleteByPrimaryKey(Integer id) {
		int updateCount = this.stockMapper.deleteByPrimaryKey(id);
		if (updateCount > 0) {
			return ServerResponse.createBySuccessMsg("操作成功");
		}
		return ServerResponse.createByErrorMsg("操作失败");
	}

}
